package org.example.security.filter;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.example.jwt.JwtHelper;
import org.example.result.ResponseUtil;
import org.example.result.Result;
import org.example.result.ResultCodeEnum;
import org.example.security.custom.CustomUser;
import org.example.vo.system.LoginVo;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class TokenLoginFilter extends UsernamePasswordAuthenticationFilter {

private RedisTemplate redisTemplate;

//    构造方法
public TokenLoginFilter(AuthenticationManager authenticationManager,
                        RedisTemplate redisTemplate) {
    this.setAuthenticationManager(authenticationManager);
    this.setPostOnly(false);
    //指定登录接口及提交方式，可以指定任意路径
    this.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/admin/system/index/login","POST"));
    this.redisTemplate= redisTemplate;
}
//    登录认证 获取输入用户名和密码，调用方法认证
@Override
public Authentication attemptAuthentication(HttpServletRequest req, HttpServletResponse res)
        throws AuthenticationException {
    try {
        LoginVo loginVo = new ObjectMapper().readValue(req.getInputStream(), LoginVo.class);
        Authentication authenticationToken = new UsernamePasswordAuthenticationToken(loginVo.getUsername(), loginVo.
                getPassword());
        return this.getAuthenticationManager().authenticate(authenticationToken);
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}
//    认证成功调用方法
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
                                        Authentication auth) throws IOException, ServletException {
    CustomUser customUser = (CustomUser) auth.getPrincipal();
    String token = JwtHelper.createToken(customUser.getSysUser().getId(),
            customUser.getSysUser().getUsername());
    //获取当前用户的权限数据，放到redis里面的key，username value 权限数据
    redisTemplate.opsForValue().set(customUser.getUsername(),
            JSON.toJSONString(customUser.getAuthorities()) );

    Map<String, Object> map = new HashMap<>();
    map.put("token", token);
    ResponseUtil.out(response, Result.ok(map));
}

//认证失败
    @Override
    protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
                                              AuthenticationException e)
            throws IOException, ServletException {
            ResponseUtil.out(response,Result.build(null,ResultCodeEnum.LOGIN_ERROR));


    }
}
